﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using Newtonsoft.Json;
using SIE.SCADA.Common.Log;
using SIE.SCADA.StationDemo.Abstract;
using SIE.SCADA.Common;
using SIE.SCADA.StationDemo.Common;
using System.Text.RegularExpressions;
#if NETSTANDARD2_0
using SIE.SCADA.IOCore.Channel.Serial;
#endif


namespace SIE.SCADA.StationDemo.SerialCommunicat
{
#if NETSTANDARD2_0
    class LinuxScannDevice : WorkerBase
    {
        private static string[] serailports;
        private LinuxSerialPort csp = null;
        private string selectedComPort = "";
        private string RecvMsg = string.Empty;
        String msg = "";
        private string _protName;
        private readonly string start = "\u0002";
        private readonly string end = "\u0003";
        private readonly string end2 = "\u000D\u000A";
        private readonly string spac = "\u0000";
        private readonly int baudRate = 9600;
        public event EventHandler<BarcodeArg> ReceveChanged;

        public LinuxScannDevice(string portName)
        {
            _protName = portName;
        }

        protected override bool Init()
        {
            return true;
        }

        private bool Load(string fileName)
        {
            return true;
        }

        public override void Start()
        {
            Logger.Info("Scanner Start!");
            GetPortNames();
            ShowPortNames();
            CloseUart(csp);
            if (string.IsNullOrEmpty(_protName)) return;
            csp = new LinuxSerialPort(_protName, baudRate);
            csp.DataReceived += Csp_DataReceived;// Csp_DataReceived;
            try
            {
                csp.Open();
                Logger.Info($"Service Open Uart [{_protName}] Succful!");
            }
            catch (Exception ex)
            {
                Logger.Error($"RunService Open Uart [{_protName}] Exception:{ex}");
            }
        }

        public void WriteBarcode(string msg)
        {
            string send = "";
            send = msg;
            csp?.WriteLine(send);
            Logger.Info($"转发数据{send}");
        }


        //public void WriteBarcode(string msg)
        //{
        //    string send = "";
        //    if (Env.StationConfig.ScanType == "2")
        //    {
        //        send = msg + "\u000D" + "\u000A";


        //    }
        //    else
        //    {
        //        send = start + msg + end;
        //    }

        //    csp?.WriteLine(send);
        //    Logger.Info($"转发数据{send}");
        //}


        //private void Csp_DataReceived3(object sender, CustomSerialPortDataReceivedEventArgs e)
        //{

        //    var serialPort = sender as LinuxSerialPort;
        //    Thread.Sleep(100);
        //    int bytesNum = serialPort.BytesToRead;

        //    if (bytesNum == 0)
        //            return;
        //        // 创建字节数组
        //        byte[] resultBuffer = new byte[bytesNum];
        //        serialPort.Read(resultBuffer, 0, bytesNum);
        //        try
        //        {
        //            string msg = Encoding.ASCII.GetString(resultBuffer);

        //            if (msg.Contains(start) && msg.Contains(end))
        //            {
        //                Regex regex = new Regex($@"(?<={start}).*?(?={end})");
        //                var resMsg = regex.Match(msg).Value;
        //                resMsg = resMsg.Replace(spac, "");
        //                ReceveChanged.Invoke(this, new BarcodeArg(resMsg));
        //                string echo = $"{serialPort.PortName} Receive Data:[{resMsg}]-------------";
        //                Logger.Info($"{echo}");
        //            }
        //            else
        //            {
        //                if(msg.Contains(start))
        //                {
        //                    sb = new StringBuilder();
        //                    sb.Append(msg);
        //                }
        //                else if(msg.Contains(end))
        //                {
        //                    sb.Append(msg);
        //                    var contact = sb.ToString();
        //                    Regex regex = new Regex($@"(?<={start}).*?(?={end})");
        //                    var resMsg = regex.Match(contact).Value;
        //                    resMsg = resMsg.Replace(spac,"");
        //                    ReceveChanged.Invoke(this, new BarcodeArg(resMsg));
        //                    string echo = $"{serialPort.PortName} Receive Data:[{resMsg}]-----------";
        //                    Logger.Info($"{echo}");
        //                }
        //            }
        //        }
        //        catch (Exception ex)
        //        {
        //            Logger.Error(ex.Message);
        //        }
        //}



        //private void Csp_DataReceived4(object sender, CustomSerialPortDataReceivedEventArgs e)
        //{

        //    var serialPort = sender as LinuxSerialPort;
        //    Thread.Sleep(100);
        //    int bytesNum = serialPort.BytesToRead;

        //    if (bytesNum == 0)
        //        return;
        //    // 创建字节数组
        //    byte[] resultBuffer = new byte[bytesNum];
        //    serialPort.Read(resultBuffer, 0, bytesNum);
        //    try
        //    {
        //        string msg = Encoding.ASCII.GetString(resultBuffer);

        //        if (msg.Contains(start) && msg.Contains(end))
        //        {
        //            Regex regex = new Regex($@"(?<={start}).*?(?={end})");
        //            var resMsg = regex.Match(msg).Value;
        //            resMsg = resMsg.Replace(spac, "");
        //            ReceveChanged.Invoke(this, new BarcodeArg(resMsg));
        //            string echo = $"{serialPort.PortName} Receive Data:[{resMsg}]-------------";
        //            Logger.Info($"{echo}");
        //        }
        //        else if(msg.EndsWith("\u000D\u000A"))
        //        {

        //            var resMsg = msg.Replace("\u000D\u000A", "");
        //            ReceveChanged.Invoke(this, new BarcodeArg(resMsg));
        //            string echo = $"{serialPort.PortName} Receive Data:[{resMsg}]-------------";
        //            Logger.Info($"{echo}");
        //        }
        //        else {

        //            var resMsg = msg;
        //            ReceveChanged.Invoke(this, new BarcodeArg(msg));
        //            string echo = $"{serialPort.PortName} Receive Data:[{resMsg}]-------------";
        //            Logger.Info($"{echo}");
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.Error(ex.Message);
        //    }
        //}

        private void Csp_DataReceived(object sender, CustomSerialPortDataReceivedEventArgs e)
        {

            var serialPort = sender as LinuxSerialPort;
            Thread.Sleep(100);
            int bytesNum = serialPort.BytesToRead;

            if (bytesNum == 0)
                return;
            // 创建字节数组
            byte[] resultBuffer = new byte[bytesNum];
            serialPort.Read(resultBuffer, 0, bytesNum);
            try
            {
                string tempdata = Encoding.ASCII.GetString(resultBuffer);
                msg +=tempdata;
                Logger.Info($"{serialPort.PortName} Receive OriginalData:[{tempdata}]-------------");
                if (msg.EndsWith(end))
                {
                    if (msg.StartsWith(start)){
                        ReceveChanged.Invoke(this, new BarcodeArg(msg));
                    }
                    Logger.Info($"{serialPort.PortName} Receive Data:[{msg}]-------------");
                    msg = "";
                }
                else if (msg.EndsWith(end2))
                {
                    ReceveChanged.Invoke(this, new BarcodeArg(msg));
                    Logger.Info($"{serialPort.PortName} Receive Data:[{msg}]-------------");
                    msg = "";
                }
                else{
                    ReceveChanged.Invoke(this, new BarcodeArg(msg));
                    Logger.Info($"{serialPort.PortName} Receive Data:[{msg}]-------------");
                    msg = "";

                }
                

            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
            }
        }


        private void ShowPortNames()
        {
            Logger.Info($"This computer has {serailports.Length} serial ports.");
            foreach (string serial in serailports)
                Logger.Info($"serial port:{serial}");
        }

        private void CloseUart(LinuxSerialPort port)
        {
            if (port != null)
            {
                port.DataReceived -= Csp_DataReceived;//Csp_DataReceived;
                if (csp.IsOpen)
                    csp.Dispose();
                port = null;
                Logger.Info($"close serial port:{_protName} succful!");
            }
        }

        //private void OpenUart(string portName)
        //{
        //    CloseUart();
        //    try
        //    {
        //        csp = new LinuxSerialPort(portName, baudRate: baudRate);
        //        csp.DataReceived += Csp_DataReceived;
        //        csp.Open();
        //        Console.WriteLine($"open serial port:{portName} succful!baudRate:{baudRate}");
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine($"Open Uart Exception:{ex}");
        //    }
        //}

        //private void TestUart(string portName)
        //{
        //    LinuxSerialPort sp;

        //    try
        //    {
        //        sp = new LinuxSerialPort(portName, baudRate);
        //        sp.Open();
        //        string msg;
        //        msg = "Hello Uart";
        //        sp.WriteLine(msg);
        //        Console.WriteLine(msg);
        //        msg = "Byebye Uart";
        //        sp.WriteLine(msg);
        //        Console.WriteLine(msg);

        //        Thread.Sleep(200);
        //        sp.Dispose();
        //        sp = null;
        //        Console.WriteLine("end " + new Random().Next());
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine($"Open Uart Exception:{ex}");
        //    }
        //}

        /// <summary>
        /// Get PortNames
        /// </summary>
        private static void GetPortNames()
        {
            serailports = LinuxSerialPort.GetPortNames();
        }

        public override void Stop()
        {
            CloseUart(csp);
        }

        protected override bool Load()
        {
            return true;
        }

        public string PortName { get; set; }
        public override bool IsRunning { get; set; }
    }
#endif
}
